%include "conf.inc"
	
	bits 16
	org	07c00h
start:
	cli
	in	al, 92h
	or	al, 000000010b
	out	92h, al
	sti
	
	mov	ax, cx
	mov	ds, ax
	mov	ss, ax
	mov	es, ax
	mov	sp, 07c00h

	call 	clear_screen

	sub	sp, 200h
	mov	bx, sp
	inc	bx
	inc	bx

	mov	bx, OffsetOfLoader
	mov	dx, BaseOfLoader
	
	mov	si, Splitline
	call	__puts
	

	mov	cx, 03h
	mov	si, bx
	call	__put_hex_data_lines

	mov	di, bx
	mov	ax, 1
	mov	cx, 20h
.load:
	stosb
	loop	.load

	mov	si, Splitline
	call	__puts
	mov	cx, 003h
	mov	si, bx
	call	__put_hex_data_lines

	jmp $
	ret

;---------------------------------------
; 以 si 为地址打印数据, 打印 16 个
;---------------------------------------
__put_hex_data_line:
	pusha
	mov	cx, 010h
.loop:
	lodsb
	call 	__put_byte
	mov	dx, si
	mov	si, ' '
	call	__putc
	mov	si, dx
	loop .loop
	popa
	ret

;---------------------------------------
; 以 si 为地址打印， 打印 cx 行
;---------------------------------------
__put_hex_data_lines:
	pusha
.loop:
	call	__put_hex_data_line
	call	__println
	add	si, 10h
	loop .loop
	popa
	ret
	
;---------------------------------
; 将 ax 以16进制形式打印出来
;---------------------------------
__put_word:	
	pusha
	mov	dx, ax
	shr	ax, 8
	call	__put_byte
	mov	ax, dx
	call	__put_byte
	popa
	ret

;---------------------------------
; 将 al 以16进制形式打印出来
;---------------------------------
__put_byte:
	pusha
	;;  print al
	mov	dl, al

	shr	al, 4
	and	al, 0x000f
	movzx	si, al
	call	__hex_to_char
	mov	si, ax
	call	__putc

	mov	al, dl
	and	al, 0x000f
	movzx	si, al 	
	call	__hex_to_char
	mov	si, ax
	call	__putc
	popa
	ret
	

; ---------------------------------
; 打印字符串
; ---------------------------------
__puts:
	pusha
	mov	ah, 0x0e
	xor	bh, bh
.loop:
	lodsb
	test	al, al
	jz	.done
	int	0x10
	jmp	.loop
.done:	
	popa
	ret

; ---------------------------------
; 将 si 打印出来
; ---------------------------------
__putc:
	push	bx
	xor	bh, bh
	mov	ax, si
	mov	ah, 0x0e
	int 	0x10
	pop	bx
	ret

__println:
	push si
	mov	si, 13
	call	__putc
	mov	si, 10
	call	__putc
	pop	si
	ret

; ---------------------------------
; clean screen
; ---------------------------------
clear_screen:
	pusha
	mov	ax, 0x0600
	xor	cx, cx
	xor	bh, 0x0f
	mov	dh, 24
	mov	dl, 79
	int 	0x10

set_position:
	mov	ah, 02
	mov	bh, 0
	mov	dx, 0
	int 	0x10
	popa
	ret

; ---------------------------------
; clean screen
; ---------------------------------
__hex_to_char:
	jmp	hex_to_char_next
	@char	db '0123456789ABCDEF', 0
hex_to_char_next:
	push	si
	and	si, 0x0f
	mov	ax, [@char + si]
	pop	si
	ret

;---------------------------------------
; read sector
; di: buffer, ax 为 sector
;---------------------------------------
__read_sector:
	push	di
	push	bx
	push	cx
	push	dx


	call	LBA_to_CHS
	mov	dl, 0
	mov	ax, 00201h
	int	0x13
	setc	al

	pop	dx
	pop	cx
	pop	bx
	pop	di
	ret

;-------------------------------------------------------
; LBA_to_CHS(): LBA mode converting CHS	mode for floppy 
; input:
;		ax - LBA sector
; output:
;		ch - cylinder
;		cl - sector (1-63)
;		dh - head	
;-------------------------------------------------------
LBA_to_CHS:
	mov cl, SPT
	div cl	; al = LBA / SPT, ah = LBA % SPT
; cylinder = LBA / SPT / HPC
	mov ch, al
	shr ch, (HPC / 2); ch = cylinder
; head = (LBA / SPT ) % HPC
	mov dh, al
	and dh, 1	; dh = head
; sector = LBA % SPT + 1
	mov cl, ah
	inc cl		; cl = sector
	ret

;--------------------------------------------------------------
; read_sector_extension(): 使用扩展功能读扇区	
; input:
;		si - sector
;		di - buf (es:di)
;----------------------------------------------------------------------
__read_sector_extension:
	xor eax, eax
	movzx esi, si
	push eax
	push esi		; 要读的扇区号 (LBA) - 64 位值
	push es
	push di			; buf 缓冲区 es:di - 32 位值
	push word 0x01		; 扇区数, word
	push word 0x10		; 结构体 size, 16 bytes
	
	mov dl, 0
	mov si, sp		; 输入结构体地址
	mov ah, 0x42		; 扩展功能号
	int 0x13	
	add sp, 0x10
	ret


Splitline:	db	'------------------------------------------------', 13, 10, 0
Failed_Read:	db	'Failed to read sector', 13, 10, 0
	times	510 - ($ - $$) db 0
	dw	0xaa55
